﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Xml.Serialization;

namespace _007_TCPIPServer
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread thr = new Thread(new ThreadStart(Server)); thr.Start(); //запускаем параллельный поток с сервером

            Console.WriteLine("Press Enter to start client");
            Console.ReadLine();

            thr.Abort();
        }

        public static void ServerInternal(Socket client) // Функция сервера, реализующая работу с клиентом
        {
            Thread.Sleep(1000);
            byte[] data = null;
            IPEndPoint newclient = (IPEndPoint)client.RemoteEndPoint;

            Console.WriteLine("Server: Connected with {0} at port {1}", newclient.Address, newclient.Port);

            NetworkStream stream = new NetworkStream(client);
            XmlSerializer serializer = new XmlSerializer(typeof(int[]));

            int[] array = (int[])serializer.Deserialize(stream);

            for (int i = 0; i < array.Length; i++) Console.WriteLine("Item={0}", array[i]);
            for (int i = 0; i < array.Length; i++) array[i] = array[i] * 2;

            serializer.Serialize(stream,array);
            stream.Flush();

                Console.WriteLine("Server: Disconnected from {0}", newclient.Address);

            client.Close();
        }

        public static void Server() // Функция сервера реализующая цикл ожидания клиентов
        {

            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);
            Socket newsock = new Socket(AddressFamily.InterNetwork,
                                        SocketType.Stream, ProtocolType.Tcp);

            newsock.Bind(ipep);
            newsock.Listen(20);
            try
            {
                int i = 0;
                do
                {

                    Console.WriteLine(String.Format("Server: Waiting for a client: {0}", ++i));
                    Socket client = newsock.Accept();
                    ThreadPool.QueueUserWorkItem(new WaitCallback((obj) => //Запускаем обработчик клиента в параллельном потоке
                    {
                        ServerInternal(client);
                    }));
                } while (true);
            }
            catch (Exception e)
            {
                Console.WriteLine("До свидания! :" + e.Message);
            }
            finally
            {
                newsock.Close();
            }
        }
    }
}
